#pragma once
#include <vector>
#include <string>
#include <map>
#include <string>
#if (defined(__clang__) && defined(_LIBCPP_VERSION)) || (__cplusplus >= 201103L)
#include <memory>
#else
#include <tr1/memory>
#endif

class BBS2chProxyURLEncodedValue {
private:
	std::string _value;
	std::string _encodedValue;
	bool _hasValue;
	bool _hasEncodedValue;
public:
	BBS2chProxyURLEncodedValue();
	BBS2chProxyURLEncodedValue(const std::string &value, bool encoded=false);
	BBS2chProxyURLEncodedValue(const char *value, size_t length, bool encoded=false);
	const std::string& get();
	const std::string& getEncoded();
	void set(const std::string &value, bool encoded=false);
	bool empty();
	BBS2chProxyURLEncodedValue& operator=(const std::string &value);
};

class BBS2chProxyFormData {
private:
	std::map<std::string, BBS2chProxyURLEncodedValue> _fields;
	std::vector<std::string> _order;
	std::string _body;
	bool _dirty;
public:
	typedef std::map<std::string, BBS2chProxyURLEncodedValue>::iterator iterator;
	BBS2chProxyFormData() {};
	BBS2chProxyFormData(const char *data, size_t length);
	std::string get(const std::string &key);
	std::string getEncoded(const std::string &key);
	void append(const std::string &key, const std::string &value, bool encoded=false);
	void set(const std::string &key, const std::string &value, bool encoded=false);
	bool has(const std::string &key);
	void remove(const std::string &key);
	void reorder(const std::vector<std::string> &order);
	const std::string& toString();
	size_t size();
	iterator begin();
	iterator end();
	std::string operator[](const std::string &key);
	static std::string decodeURIComponent(const char *input, size_t inputLength, bool decodePlus);
	static std::string encodeURIComponent(const char *input, size_t inputLength, bool spaceAsPlus);
};

#if (defined(__clang__) && defined(_LIBCPP_VERSION)) || (__cplusplus >= 201103L)
typedef std::shared_ptr<BBS2chProxyFormData> PBBS2chProxyFormData;
#else
typedef std::tr1::shared_ptr<BBS2chProxyFormData> PBBS2chProxyFormData;
#endif
